/**
 * Copyright (c) Tapas Mobile.  All Rights Reserved.
 *
 * @author DaiHui 
 * @version 1.0
 */

package com.dotools.compat;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.dotools.debug.LOG;

import android.annotation.TargetApi;
import android.app.SearchManager;
import android.appwidget.AppWidgetHost;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.net.ConnectivityManager;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.view.VelocityTracker;
import android.view.View;

public class MissedAPI {
    public static final String android_provider_Settings_ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS;
    public static final String android_provider_Settings_MOBILE_DATA;
    public static final int android_os_Power_BRIGHTNESS_ON;
    public static final int WifiManager_WIFI_AP_STATE_ENABLING;
    public static final int WifiManager_WIFI_AP_STATE_ENABLED;
    public static final int WifiManager_WIFI_AP_STATE_FAILED;

    //for com.android.internal.R
    public static final String com_android_internal_R_styleable = "com.android.internal.R$styleable";
    public static int[] com_android_internal_R_styleable_AppWidgetProviderInfo;
    public static int com_android_internal_R_styleable_AppWidgetProviderInfo_minWidth;
    public static int com_android_internal_R_styleable_AppWidgetProviderInfo_minHeight;
    public static int com_android_internal_R_styleable_AppWidgetProviderInfo_updatePeriodMillis;
    public static int com_android_internal_R_styleable_AppWidgetProviderInfo_initialLayout;
    public static int com_android_internal_R_styleable_AppWidgetProviderInfo_configure;

    public static String Intent_EXTRA_CHANGED_PACKAGE_LIST;
    public static String Intent_ACTION_EXTERNAL_APPLICATIONS_AVAILABLE;
    public static String Intent_ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;

    public static int MotionEvent_ACTION_POINTER_INDEX_SHIFT;
    public static int MotionEvent_ACTION_POINTER_INDEX_MASK;

    static Method methodSameAs;
    static Method methodGetXVelocityInt;
    static Method methodGetXVelocityVoid;
    static Method methodCurrentToCanonicalPackageNames;
    static Method methodGetGlobalSearchActivity;
    static Method methodConnectivityManager_getMobileDataEnabled;
    static Method methodConnectivityManager_setMobileDataEnabled;
    static Method methodWifiManager_getWifiApState;
    static Method methodWifiManager_setWifiApEnabled;
    static Method methodAppWidgetHost_clearViews;

    static {
        ClassLoader cl = ClassLoader.getSystemClassLoader();

        //BEGIN load com.android.internal.R some value
        try {
            Class<?> cls = cl.loadClass(com_android_internal_R_styleable);
            Field fld = cls.getDeclaredField("AppWidgetProviderInfo");
            com_android_internal_R_styleable_AppWidgetProviderInfo = (int[]) fld.get(null);
            Field fld2 = cls.getDeclaredField("AppWidgetProviderInfo_configure");
            com_android_internal_R_styleable_AppWidgetProviderInfo_configure = (Integer) fld2.get(null);
            Field fld3 = cls.getDeclaredField("AppWidgetProviderInfo_initialLayout");
            com_android_internal_R_styleable_AppWidgetProviderInfo_initialLayout = (Integer) fld3.get(null);
            Field fld4 = cls.getDeclaredField("AppWidgetProviderInfo_minHeight");
            com_android_internal_R_styleable_AppWidgetProviderInfo_minHeight = (Integer) fld4.get(null);
            Field fld5 = cls.getDeclaredField("AppWidgetProviderInfo_minWidth");
            com_android_internal_R_styleable_AppWidgetProviderInfo_minWidth = (Integer) fld5.get(null);
            Field fld6 = cls.getDeclaredField("AppWidgetProviderInfo_updatePeriodMillis");
            com_android_internal_R_styleable_AppWidgetProviderInfo_updatePeriodMillis = (Integer) fld6.get(null);
        } catch (Exception e) {
        }
        //END load com.android.internal.R some value

        // load values by reflection
        String temp_ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS";
        try {
            Class<?> cls = android.provider.Settings.class; // cl.loadClass("android.provider.Settings");
            Field fld = cls.getDeclaredField("ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS");
            temp_ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = (String) fld.get(null);
        } catch (Exception e) {
        }
        android_provider_Settings_ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = temp_ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS;
        // LOG.logI(android_provider_Settings_ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS);

        String temp_MOBILE_DATA = "mobile_data";
        try {
            Class<?> cls = cl.loadClass("android.provider.Settings.Secure");
            Field fld = cls.getDeclaredField("MOBILE_DATA");
            temp_MOBILE_DATA = (String) fld.get(null);
        } catch (Exception e) {
            try {
                Class<?> cls = cl.loadClass("android.provider.Settings.Global");
                Field fld = cls.getDeclaredField("MOBILE_DATA");
                temp_MOBILE_DATA = (String) fld.get(null);
            } catch (Exception e1) {
            }
        }
        android_provider_Settings_MOBILE_DATA = temp_MOBILE_DATA;
        // LOG.logI(android_provider_Settings_MOBILE_DATA);

        int temp_BRIGHTNESS_ON = 255;
        try {
            Class<?> cls = Class.forName("android.os.Power");
            Field field = cls.getDeclaredField("BRIGHTNESS_ON");
            temp_BRIGHTNESS_ON = field.getInt(null);
        } catch (ClassNotFoundException e) {
            try {
                Class<?> cls = Class.forName("android.os.PowerManager");
                Field field = cls.getDeclaredField("BRIGHTNESS_ON");
                temp_BRIGHTNESS_ON = field.getInt(null);
            } catch (ClassNotFoundException e1) {
            } catch (NoSuchFieldException e1) {
            } catch (IllegalArgumentException e1) {
            } catch (IllegalAccessException e1) {
            }
        } catch (NoSuchFieldException e) {
        } catch (IllegalArgumentException e) {
        } catch (IllegalAccessException e) {
        }
        android_os_Power_BRIGHTNESS_ON = temp_BRIGHTNESS_ON;

        int temp_WIFI_AP_STATE_ENABLING = 12;
        try {
            Class<?> cls = WifiManager.class;
            Field field = cls.getDeclaredField("WIFI_AP_STATE_ENABLING");
            temp_WIFI_AP_STATE_ENABLING = field.getInt(null);
        } catch (Exception e) {
        }
        WifiManager_WIFI_AP_STATE_ENABLING = temp_WIFI_AP_STATE_ENABLING;

        int temp_WIFI_AP_STATE_ENABLED = 13;
        try {
            Class<?> cls = WifiManager.class;
            Field field = cls.getDeclaredField("WIFI_AP_STATE_ENABLING");
            temp_WIFI_AP_STATE_ENABLED = field.getInt(null);
        } catch (Exception e) {
        }
        WifiManager_WIFI_AP_STATE_ENABLED = temp_WIFI_AP_STATE_ENABLED;

        int temp_WIFI_AP_STATE_FAILED = 12;
        try {
            Class<?> cls = WifiManager.class;
            Field field = cls.getDeclaredField("WIFI_AP_STATE_FAILED");
            temp_WIFI_AP_STATE_ENABLING = field.getInt(null);
        } catch (Exception e) {
        }
        WifiManager_WIFI_AP_STATE_FAILED = temp_WIFI_AP_STATE_FAILED;

        try {
            Class<?> cls = android.content.Intent.class; // cl.loadClass("android.content.Intent");
            Field fld = cls.getDeclaredField("EXTRA_CHANGED_PACKAGE_LIST");
            Intent_EXTRA_CHANGED_PACKAGE_LIST = (String) fld.get(null);
        } catch (Exception e) {
            Intent_EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
        }
        // LOG.logI(Intent_EXTRA_CHANGED_PACKAGE_LIST);

        try {
            Class<?> cls = android.content.Intent.class; // cl.loadClass("android.content.Intent");
            Field fld = cls.getDeclaredField("ACTION_EXTERNAL_APPLICATIONS_AVAILABLE");
            Intent_ACTION_EXTERNAL_APPLICATIONS_AVAILABLE = (String) fld.get(null);
        } catch (Exception e) {
            Intent_ACTION_EXTERNAL_APPLICATIONS_AVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE";
        }
        // LOG.logI(Intent_ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);

        try {
            Class<?> cls = android.content.Intent.class; // cl.loadClass("android.content.Intent");
            Field fld = cls.getDeclaredField("ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE");
            Intent_ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE = (String) fld.get(null);
        } catch (Exception e) {
            Intent_ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE";
        }
        // LOG.logI(Intent_ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);

        try {
            Class<?> cls = android.view.MotionEvent.class; // cl.loadClass("android.view.MotionEvent");
            Field fld = cls.getDeclaredField("ACTION_POINTER_INDEX_SHIFT");
            MotionEvent_ACTION_POINTER_INDEX_SHIFT = (Integer) fld.get(null);
        } catch (Exception e) {
            MotionEvent_ACTION_POINTER_INDEX_SHIFT = 8;
        }
        // LOG.logI("MotionEvent_ACTION_POINTER_INDEX_SHIFT " + MotionEvent_ACTION_POINTER_INDEX_SHIFT);

        try {
            Class<?> cls = android.view.MotionEvent.class; // cl.loadClass("android.view.MotionEvent");
            Field fld = cls.getDeclaredField("ACTION_POINTER_INDEX_MASK");
            MotionEvent_ACTION_POINTER_INDEX_MASK = (Integer) fld.get(null);
        } catch (Exception e) {
            MotionEvent_ACTION_POINTER_INDEX_MASK = 0xff00;
        }
        // LOG.logI("MotionEvent_ACTION_POINTER_INDEX_MASK " + MotionEvent_ACTION_POINTER_INDEX_MASK);

        try {
            Class<?> clsVelocityTracker = android.graphics.Bitmap.class; // cl.loadClass("android.graphics.Bitmap");
            methodSameAs = clsVelocityTracker.getDeclaredMethod("sameAs", new Class<?>[] {
                android.graphics.Bitmap.class
            });
        } catch (Exception e) {
        }

        try {
            Class<?> clsVelocityTracker = android.view.VelocityTracker.class; // cl.loadClass("android.view.VelocityTracker");
            methodGetXVelocityInt = clsVelocityTracker.getDeclaredMethod("getXVelocity", new Class<?>[] {
                int.class
            });
            methodGetXVelocityVoid = clsVelocityTracker.getDeclaredMethod("getXVelocity", new Class<?>[] {});
        } catch (Exception e) {
        }

        try {
            Class<?> clsPackageManager = android.content.pm.PackageManager.class; // cl.loadClass("android.content.pm.PackageManager");
            methodCurrentToCanonicalPackageNames = clsPackageManager.getDeclaredMethod(
                    "currentToCanonicalPackageNames", new Class<?>[] {
                        String[].class
                    });
        } catch (Exception e) {
        }

        try {
            Class<?> clsSearchManager = android.content.pm.PackageManager.class; // cl.loadClass("android.content.pm.PackageManager");
            methodGetGlobalSearchActivity = clsSearchManager.getDeclaredMethod("getGlobalSearchActivity",
                    new Class<?>[] {});
        } catch (Exception e) {
        }

        try {
            Class<?> clsConnectivityManager = android.net.ConnectivityManager.class;
            methodConnectivityManager_getMobileDataEnabled = clsConnectivityManager
                    .getDeclaredMethod("getMobileDataEnabled", new Class<?>[] {});
        } catch (NoSuchMethodException e) {
        }

        try {
            Class<?> clsConnectivityManager = android.net.ConnectivityManager.class;
            methodConnectivityManager_setMobileDataEnabled = clsConnectivityManager
                    .getDeclaredMethod("setMobileDataEnabled", new Class<?>[] {
                        boolean.class
                    });
        } catch (NoSuchMethodException e) {
        }

        try {
            Class<?> clsWifiManager = WifiManager.class;
            methodWifiManager_getWifiApState = clsWifiManager.getDeclaredMethod("getWifiApState",
                    new Class<?>[] {});
        } catch (NoSuchMethodException e) {
        }

        try {
            Class<?> clsWifiManager = WifiManager.class;
            methodWifiManager_setWifiApEnabled = clsWifiManager.getDeclaredMethod(
                    "setWifiApEnabled", new Class<?>[] {
                            WifiConfiguration.class, boolean.class
                    });
        } catch (NoSuchMethodException e) {
        }

        try {
            Class<?> clazzAppWidgetHost = AppWidgetHost.class;
            methodAppWidgetHost_clearViews = clazzAppWidgetHost.getDeclaredMethod("clearViews",
                    new Class<?>[0]);
            methodAppWidgetHost_clearViews.setAccessible(true);
        } catch (NoSuchMethodException e) {
        }
    }

    public static void init() {
        // reference the class to run static initializer
        LOG.logI("Init MissedAPI");
    }

    public static boolean Bitmap_sameAs(Bitmap lhs, Bitmap rhs) {
        if (methodSameAs != null) {
            try {
                return (Boolean) methodSameAs.invoke(lhs, rhs);
            } catch (Exception e) {
            }
        }

        if (lhs != null)
            return lhs.equals(rhs);

        return false;
    }

    public static float VelocityTracker_getXVelocity(VelocityTracker obj, int argument) {
        if (methodGetXVelocityInt != null) {
            try {
                return (Float) methodGetXVelocityInt.invoke(obj, argument);
            } catch (Exception e) {
            }
        }

        return obj.getXVelocity();
    }

    public static String[] PackageManager_currentToCanonicalPackageNames(PackageManager obj, String[] strings) {
        if (methodCurrentToCanonicalPackageNames != null) {
            try {
                return (String[]) methodCurrentToCanonicalPackageNames.invoke(obj, (Object) strings);
            } catch (Exception e) {
            }
        }
        return strings;
    }

    public static ComponentName SearchManager_getGlobalSearchActivity(SearchManager obj) {
        if (methodGetGlobalSearchActivity != null) {
            try {
                return (ComponentName) methodGetGlobalSearchActivity.invoke(obj, (Object) null);
            } catch (Exception e) {
            }
        }
        return null;
    }

    public static boolean ConnectivityManager_getMobileDataEnabled(ConnectivityManager cnm) {
        if (methodConnectivityManager_getMobileDataEnabled != null) {
            try {
                return (Boolean) methodConnectivityManager_getMobileDataEnabled.invoke(cnm);
            } catch (Exception e) {
                return false;
            }
        }
        return false;
    }

    public static void ConnectivityManager_setMobileDataEnabled(ConnectivityManager cnm,
            boolean enabled) {
        if (methodConnectivityManager_setMobileDataEnabled != null) {
            try {
                methodConnectivityManager_setMobileDataEnabled.invoke(cnm, enabled);
            } catch (Exception e) {
                return;
            }
        }
        return;
    }

    public static int WifiManager_getWifiApState(WifiManager wm) {
        if (methodWifiManager_getWifiApState != null) {
            try {
                return (Integer) methodWifiManager_getWifiApState.invoke(wm);
            } catch (Exception e) {
                return WifiManager_WIFI_AP_STATE_FAILED;
            }
        }
        return WifiManager_WIFI_AP_STATE_FAILED;
    }

    public static boolean WifiManager_setWifiApEnabled(WifiManager wm,
            WifiConfiguration wifiConfig, boolean enabled) {
        if (methodWifiManager_setWifiApEnabled != null) {
            try {
                return (Boolean) methodWifiManager_setWifiApEnabled.invoke(wm, wifiConfig, enabled);
            } catch (Exception e) {
                return false;
            }
        }
        return false;
    }

    public static void Canvas_setBitmap(Canvas canvas, Bitmap bitmap) {
        if (bitmap != null) {
            canvas.setBitmap(bitmap);
        } else {
            if (Build.VERSION.SDK_INT >= 14) {
                canvas.setBitmap(null);
            }
        }
    }

    public static void AppWidgetHost_clearViews(AppWidgetHost host) {
        if(methodAppWidgetHost_clearViews != null) {
            try {
                methodAppWidgetHost_clearViews.invoke(host, new Object[0]);
            } catch (IllegalArgumentException e) {
            } catch (IllegalAccessException e) {
            } catch (InvocationTargetException e) {
            }
        }
    }
}
